﻿using DataProcess.Interface;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.IO;
using System.Linq;

namespace DataDrive.DataBase
{
    public class DataDrive : IDataDrive
    {
        /// <summary>
        /// 用于数据库操作
        /// </summary>
        private SqlSugarClient Db { get; set; }

        private Config Config;

        public event StartedHandler Started;
        public event StopedHandler Stoped;
        public event DataRecivedHandler DataRecived;
        public event ErrorNoticedHandler ErrorNoticed;
        public event WarnNoticedHandler WarnNoticed;
        public event InfoNoticedHandler InfoNoticed;
        public string Name
        {
            get
            {
                return $"文件路径({$"{Path.Combine(Config.FolderPath, Config.FileName)}"})";
            }
        }
        public string SourceName { get; set; }


        public bool Running
        {
            get
            {
                if (_queryTimer == null) return false;
                return _queryTimer.Enabled;
            }
        }

        System.Timers.Timer _queryTimer;

        public DataDrive(Config config)
        {
            Config = config;
            _queryTimer = new System.Timers.Timer();
            _queryTimer.Interval = Config.Interval * 1000;
            _queryTimer.Elapsed -= new System.Timers.ElapsedEventHandler(DataHandle);
            _queryTimer.Elapsed += new System.Timers.ElapsedEventHandler(DataHandle);
        }
     
        string connStr = string.Empty;
        public void Start()
        {
            if (Config == null) return;

            if (!Config.Valided())
            {
                WarnNoticed?.Invoke($"数据驱动配置不全,无法启用驱动.详情如下:{Config.Message}");
                return;
            }
            string msg = string.Empty;
            try
            {
                connStr = @"DataSource=" + Config.FolderPath + "\\" + Config.FileName;
                Db = new SqlSugarClient(new ConnectionConfig()
                {
                    ConnectionString = connStr,
                    DbType = SqlSugar.DbType.Sqlite,
                    IsAutoCloseConnection = true,
                    InitKeyType = InitKeyType.SystemTable,
                    //MoreSettings = new ConnMoreSettings { IsWithNoLockQuery = true }
                });
                  msg = $@"开始加载文件[{Config.FolderPath}\{Config.FileName}数据库驱动]";
                StartTimer();
                InfoNoticed?.Invoke(msg);
                Started?.Invoke();
            }
            catch (Exception ex)
            {
                Db?.Close();
                Db?.Dispose();
                ErrorNoticed?.Invoke(ex.Message);
            }

        }

        //定时任务
        private void StartTimer()
        {
            InfoNoticed?.Invoke($@"定时查询任务启动");
            _queryTimer.Enabled = true;
            _queryTimer.Start();
        }

        private void DataHandle(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (Db == null)
                {
                    WarnNoticed?.Invoke($"数据驱动未开启");
                    return;
                }
                DateTime dt = DateTime.Parse(Convert.ToString(Config.Date));
                string configDate = dt.ToString("yyyy-MM-dd HH:mm:ss");
                var dbList = Db.SqlQueryable<Result>($"{Config.Sql} where createDate>'{configDate}' and stad is not null").ToList();
                if (dbList.Count == 0) return;
                IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy/MM/dd HH:mm:ss" };
                string dataStr = JsonConvert.SerializeObject(dbList, dtConverter);
                List<Dictionary<string, string>> dataListDate = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(dataStr);
                string maxDate =dataListDate.OrderBy(dict => dict["createDate"]).Last()["createDate"];
                Config.Date = Convert.ToDateTime(maxDate.Replace("/", "-"));
                DataRecived?.Invoke(JsonConvert.SerializeObject(dataListDate, dtConverter));

            }
            catch (Exception ex)
            {
                Db?.Close();
                Db?.Dispose();
                ErrorNoticed?.Invoke(ex.Message);
            }
            finally
            {
                Db?.Close();
            }
        }

        public void Stop()
        {
            _queryTimer?.Close();
            Db?.Close();
            Stoped?.Invoke();
        }

        public void Dispose()
        {
            _queryTimer?.Close();
            _queryTimer?.Dispose();
            Db?.Close();
            Db?.Dispose();
        }
    }
    public class Config : IDataDriveConfig
    {
        [Display(Name = "文件夹路径")]
        public string FolderPath { get; set; }

        [Display(Name = "要读取的文件")]
        public string FileName { get; set; }

        [Display(Name = "Sql语句")]
        public string Sql { get; set; }

        [Display(Name = "定时查询数据(秒)")]
        public int Interval { get; set; }

        [Display(Name = "查询时间点")]
        public DateTime Date { get; set; }

        [Display(AutoGenerateField = false)]
        public string Message { get; set; }

        public bool Valided()
        {
            if (string.IsNullOrEmpty(FolderPath))
            {
                Message = "[文件夹路径]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(FileName))
            {
                Message = "[文件名称]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(Sql))
            {
                Message = "[Sql语句]不能为空";
                return false;
            }

            if (string.IsNullOrEmpty(Interval.ToString()))
            {
                Message = "[定时查询数据(秒)]不能为空";
                return false;
            }
            if (string.IsNullOrEmpty(Date.ToString()))
            {
                Message = "查询条件不能为空";
                return false;
            }
            return true;
        }
    }

    [SugarTable("Result")]
    public class Result
    {
        [SugarColumn(IsIgnore = true)]
        public string autoNum { get; set; }
        [SugarColumn(IsIgnore = true)]
        public string manualNum { get; set; }
        [SugarColumn(IsIgnore = true)]
        public double stad { get; set; }
        [SugarColumn(IsIgnore = true)]
        public DateTime createDate { get; set; }
        [SugarColumn(IsIgnore = true)]
        public DateTime testItme { get; set; }
    }
}
